/*
 * @Author: Yang Zhang
 * @Date: 2021-11-18 22:13:19
 * @LastEditors: Yang Zhang
 * @LastEditTime: 2021-12-22 10:28:25
 * @Description: 请求封装
 */
import axios from 'axios'
import store from '../store'
// import store from '@/store'
import { message } from 'ant-design-vue';
import { RefreshToken } from '../api/app';
import { getStorageItem, setStorageItem } from './utils';
import router from '../router';

const baseUrl = import.meta.env.VITE_BASE_API
const storeUrl = import.meta.env.VITE_BASE_STORE_APIlet
const realUrl = 'https://www.intere.store'
let isRefreshToken = 0
const refreshToken = getRefreshtoken()



function getRefreshtoken() {
  let lock = false;
  let success = false;
  return function () {
    if (!lock) {
      lock = true;
      let oldRefreshToken = store.state.user.refreshToken || getStorageItem('refreshToken');
      RefreshToken(oldRefreshToken)
        .then(res => {
          if (res.success) {
            store.dispatch('user/updateAccessToken', res.result.accessToken)
            store.dispatch('user/updateRefreshToken', res.result.refreshToken)
            success = true;
            lock = false;
          } else {
            success = false;
            lock = false;
            router.push('/login')
          }
        })
        .catch(err => {
          success = false;
          lock = false;
        });
    }
    return new Promise(resolve => {
      // 一直看lock,直到请求失败或者成功
      const timer = setInterval(() => {
        if (!lock) {
          clearInterval(timer);
          if (success) {
            resolve("success");
          } else {
            resolve("fail");
          }
        }
      }, 500); // 轮询时间间隔
    });
  };
}
//  401跳转
function noAuth() {
  // console.log('401', store)
  window.localStorage.clear()
  window.location.href = '/'
}

const CancelToken = axios.CancelToken
let cancel
const curRequest: any = {}

//  缓存当前请求  设置存储对象
const setCurRequest = (url: string, data: any = {}, requestCancel: any, isNeedClear = false) => {
  const keys = Object.keys(data)
  let requestKey = url
  const symbol = '-'

  if (!isNeedClear) {
    keys.forEach((key) => {
      const val = data[key]
      requestKey += symbol + key + symbol + val
    })
  }

  //  清空上一次请求
  if (curRequest[requestKey]) {
    curRequest[requestKey]()
    curRequest[requestKey] = null
  }

  curRequest[requestKey] = requestCancel
}

const cleanRequestList = () => {
  const keys = Object.keys(curRequest)

  keys.forEach((key) => {
    const cancel = curRequest[key]
    cancel && cancel()
    curRequest[key] = null
  })
}

const request = (opt: any) => {
  const { method, url, params, data } = opt
  opt.notErrTips = false

  const axiosOptions: any = {
    // baseURL: '/api/crris',
    baseURL: realUrl,
    method,
    url,
    params, // get
    data, // post
    transformRequest: [
      (data: any) => {
        // 对 data 进行任意转换处理
        if (opt.formData) {
          const formData = new FormData()
          for (const key in data) {
            // console.log('request key', /\[\]$/.test(key))
            if (/\[\]$/.test(key)) {
              //  console.log(`/\[\]$/.test(key)`, true)
              data[key].forEach((v: any) => {
                formData.append(key, v)
              })
            } else {
              formData.append(key, data[key])
            }
          }
          return formData
        }
        //  return qs.stringify(data)
        return JSON.stringify(data)
      }
    ],
    headers: (() => {
      const headers = opt.headers || {
        'Content-Type': opt.formData
          ? 'application/x-www-form-urlencoded'
          : 'application/json; charset=utf-8',
        'uuid': store.state.app.uuid,
        'accessToken': store.state.user.accessToken || ''
        // 'Content-Type': 'application/json; charset=utf-8',
      }

      return headers
    })(),
    cancelToken: new CancelToken(function executor(c: any) {
      cancel = c
      setCurRequest(url, method.toUpperCase() === 'GET' ? params : data, cancel, opt.isNeedClear)
    })
  }
  return axios(axiosOptions)
    .then((response: { data: any; }) => {
      const body = response.data
      if (body.code === 200 && !body.success && body.message) {
        message.error(body.message)
      }
      if(body.code !== 200){
        showErrorMessage(body.message)
      }
      switch (body.code) {
        case 400:
          if (body.message !== null) {
            message.error(body.message);
          } else {
            message.error("system error");
          }
          break;
        case 403:
          store.dispatch('user/updateAccessToken', '')
          store.dispatch('user/updateRefreshToken', '')
          router.push('/login')
          break;
        case 401:
          store.dispatch('user/updateAccessToken', '')
          store.dispatch('user/updateRefreshToken', '')
          router.push('/login')
          break;
        case 500:
          // system error
          if (body.message !== null) {
            message.error(body.message);
          } else {
            message.error("system error");
          }
          break;
        default:
          return body;
      }
      return body
    })
    .catch(async (err: { response: any; message: string; }) => {
      const res = err.response
      if (!res) {
        showErrorMessage(res.data.message)
        return false
      }

      const code = res && res.status
      console.log(code)
      console.log(res)
      const data = res.data

      const errTips = data && data.data && data.data.message

      if (code === 400) {
        showErrorMessage(res.data.message)
        return false
      }

      if (code === 401) {
        noAuth()
        return
      }

      if (code === 403) {
        store.dispatch('user/updateAccessToken', '')
        store.dispatch('user/updateRefreshToken', '')
        router.push('/login')
        // // 刷新token
        // isRefreshToken++;
        // if (isRefreshToken === 1) {
        //   const getTokenRes = await refreshToken();
        //   console.log('getTokenRes', getTokenRes)
        //   if (getTokenRes === "success") {
        //     // 刷新token
        //     if (isRefreshToken === 1) {
        //       err.response.config.headers.accessToken = getStorageItem(
        //         "accessToken"
        //       );
        //       // return service(error.response.config);
        //     } else {
        //       router.go(0);
        //     }
        //   } else {
        //     router.push("/login");
        //   }
        //   isRefreshToken = 0;
        // }
      } else {
        // // 其他错误处理
        // message.error(err.response.data.message);
        // if (err.response.data.code == 20004) {
        //   store.dispatch('user/updateAccessToken', '')
        //   store.dispatch('user/updateRefreshToken', '')
        //   router.push('/login')
        // }
        showErrorMessage(res.data.message || res.data.error)
      }
    }
    )
}

function showErrorMessage(errTips: string) {
  message.error(errTips)
}

export { request, cleanRequestList }

